<script setup lang="ts">
//@ts-nocheck
import { ref } from "vue";
import DeviceCategoryApi from "@/api/DeviceCategoryApi";
import {
  addPolyline,
  updatePoint,
  updatePolyline,
  uploadImg,
} from "@/api/pipe/index";
import { useMapStore } from "@/store/modules/map";
import { useLocalStore } from "@/views/pipe-network/store";
import _ from "lodash";
import { changeDateFormat } from "@/utils";
import { getAddressByLonLat } from "@/utils/map";
const mapStore = useMapStore();
const IMG_BASE_URL = import.meta.env.VITE_APP_API_OSS;
const centerDialogVisible = ref(true);
const typeRef = ref("");
const typeOptions = ref([]);
const dynamicFields = ref([]);
const ruleFormRef = ref();
const length = ref(0);
const upload = ref();
const imgManager = ref({});
const emitEvents = defineEmits(["close"]);
const params = {
  pageSize: 1000,
  pageIndex: 1,
  pClassId: "02",
};
const localStore = useLocalStore();
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const isRepeatSubmit = ref(false);

const getDeviceCategoryList = () => {
  DeviceCategoryApi.api_query(params).then(({ data, errors, succeeded }) => {
    if (succeeded) {
      typeOptions.value = data.items.map((item: any) => {
        const { className, classId, classAttribute } = item;
        return {
          value: classId,
          label: className,
          fields: classAttribute,
        };
      });
      typeRef.value = data.items[0].className;
      dynamicFields.value = data.items[0].classAttribute;
    }
  });
};
const onChange = (value: any) => {
  const { fields, label } = typeOptions.value.find(
    (item) => item.value === value
  );
  if (Array.isArray(dynamicFields.value)) {
    dynamicFields.value.forEach((item: any) => {
      delete rules[item.attr];
      delete form[item.attr];
    });
  }
  fields.forEach((item) => {
    /**
     * 图片类型的字段，值改成数组，方便扩展成支持6张图片
     */
    if (item.type === 4) {
      if (typeof item.value === "string") {
        item.value = item.value ? [{ url: IMG_BASE_URL + item.value }] : [];
      }
    }
  });
  dynamicFields.value = fields;
  fields.forEach((field: any) => {
    form[field.attr] = field.value;
  });
  form.classId = value;
  form.className = label;
};
const dealWithParams = (params, fields) => {
  fields.forEach((field: any) => {
    const { attr } = field;
    if (attr === "口径" || attr === "管径") {
      const radius = params[attr];
      if (isFinite(radius)) {
        field.value = Number(radius);
      } else {
        field.value = radius;
      }
    } else {
      field.value = params[attr];
    }
    delete params[attr];
  });
  params.lineAttribute = fields;
  params.workStartDate = changeDateFormat(params.workStartDate);
  params.length = length.value * 1000;
  params.diameter = getField(params, "管径");
  params.caliber = getField(params, "口径");
  params.tubing = getField(params, "管材");
  return params;
};
const props = defineProps({
  positions: Array<any>, // 接收父组件传过来的点位坐标
  editor: Object,
  lineDepth: Number,
});
const form = reactive({
  lineName: "",
  classId: "",
  className: "",
  depth: props.lineDepth,
  diameter: 0, // 直径
  caliber: 0, // 口径
  tubing: "",
  workStartDate: "",
  lineAttribute: "",
  jsonLine: "",
  remark: "",
});

const getField = (data: any, field: string) => {
  const { lineAttribute } = data;
  if (Array.isArray(lineAttribute)) {
    const obj = lineAttribute.find((item: any) => item.attr === field);
    if (obj) {
      if (obj.type === 4) return "";
      return obj.value;
    }
  }
  return "";
};
const rules = reactive({
  className: [{ required: true, message: "请选择管段类型" }],
  lineName: [
    {
      required: true,
      message: "请输入管段名称",
    },
  ],
});
const changeUpload = async (_data, attr) => {
  const rst = beforeUpload(_data, attr);
  if (rst) {
    const list = imgManager.value[attr];
    if (!list) {
      imgManager.value[attr] = [_data.raw];
    } else {
      imgManager.value[attr].push(_data.raw);
    }
  }
};
const beforeUpload = (file, attr) => {
  const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
  const whiteList = ["jpg", "jpeg", "png", "bmp", "JPG", "JPEG", "BMP"];
  if (whiteList.indexOf(fileSuffix) === -1) {
    ElMessage.error("上传文件只能是jpg,jpeg,png,bmp,JPG,JPEG,BMP格式");
    form[attr].pop();
    return false;
  }
  const isLt2M = file.size / 1024 / 1024 < 5;
  if (!isLt2M) {
    ElMessage.error("上传文件大小不能超过 5MB");
    form[attr].pop();
    return false;
  }
  return true;
};
const checkLength = (e, prop, maxLength) => {
  let b = 0; // 输入的字符数
  for (let i = 0, length = e.length; i < length; i++) {
    let c = e.charAt(i);
    if (/^[\u0000-\u00ff]$/.test(c)) {
      b++;
    } else {
      b += 2;
    }
    if (b > maxLength) {
      // 字符长度限制
      form[prop] = e.substr(0, i);
      if (/^[\u0000-\u00ff]$/.test(c)) {
        b--;
      } else {
        b -= 2;
      }
      break;
    }
  }
};
const handlePictureCardPreview = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
const onClose = () => {
  if (mapStore?.editingPipeLine) {
    mapStore.setEditingPipeLine(null);
  }
  emitEvents("close");
};
const updateRules = () => {
  const fields = dynamicFields.value;
  fields.forEach((field: any) => {
    rules[field.attr] = [
      {
        required: field.require,
        message: `请输入${field.attr}`,
      },
    ];
  });
};
const onSubmit = async (formEl) => {
  if (!formEl) return;
  if (isRepeatSubmit.value) {
    ElMessage.warning("正在保存中...");
    return;
  }
  updateRules();
  const { editor } = props;
  let imgUpdateFailFlag = false;
  isRepeatSubmit.value = true;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      ElMessage.warning("正在保存中...");
      isRepeatSubmit.value = true;
      const loop = async () => {
        for (let key in imgManager.value) {
          const list = form[key];
          const pathList = [];
          for (let i = 0; i < list.length; i++) {
            const { url } = list[i];
            if (url?.includes(IMG_BASE_URL)) {
              pathList.push(list[i]);
            } else {
              const { uid } = list[i];
              const file = imgManager.value[key].find(
                (item) => item.uid == uid
              );
              const rst = await uploadImg(file);
              if (rst.statusCode === 400) {
                ElMessage.error("图片上传失败！");
                imgUpdateFailFlag = true;
                return;
              }
              pathList.push({ url: IMG_BASE_URL + rst.data.path });
            }
          }
          form[key] = pathList;
        }
      };
      await loop();
      if (!imgUpdateFailFlag) {
        if (editor) {
          updatePolyline(dealWithParams(form, dynamicFields.value)).then(
            (res) => {
              if (res.statusCode === 200) {
                centerDialogVisible.value = false;
                ElMessage({
                  message: "修改成功。",
                  type: "success",
                });
              }
              localStore.addUpdateLineAPICount();
            }
          );
        } else {
          addPolyline(dealWithParams(form, dynamicFields.value)).then((res) => {
            if (res.statusCode === 200) {
              centerDialogVisible.value = false;
              ElMessage({
                message: "已保存成功。",
                type: "success",
              });
              localStore.addUpdateLineAPICount();
            } else {
              ElMessage({
                message: res.errors,
                type: "error",
              });
            }
          });
        }
        emitEvents("close");
      }
      isRepeatSubmit.value = false;
    } else {
      isRepeatSubmit.value = false;
    }
  });
};
const onSubmitDebounce = _.debounce(onSubmit, 2000, {
  leading: false,
  trailing: true,
});
watchEffect(() => {
  if (props.positions?.length > 1) {
    const len = props.positions.reduce((pre, cur, index, list) => {
      if (index > 0) {
        pre += L.latLng(list[index - 1]).distanceTo(L.latLng(cur));
      }
      return pre;
    }, 0);
    length.value = (len / 1000).toFixed(4);
    form.jsonLine = JSON.stringify(
      props.positions.map((item) => [item.lng, item.lat])
    );

    getAddressByLonLat(props.positions[0].lng, props.positions[0].lat).then(
      (res) => {
        if (res.status === "1") {
          const {
            regeocode: { formatted_address },
          } = res;
          form.startPointName = formatted_address;
        }
      }
    );

    getAddressByLonLat(
      props.positions[props.positions.length - 1].lng,
      props.positions[props.positions.length - 1].lat
    ).then((res) => {
      if (res.status === "1") {
        const {
          regeocode: { formatted_address },
        } = res;
        form.endPointName = formatted_address;
      }
    });
  }
});
watchEffect(() => {
  const { editor } = props;
  if (editor) {
    let { lineAttribute = [], length: len, workStartDate } = editor;
    const someDynamicFields = {};
    if (typeof pointAttribute === "string") {
      pointAttribute = JSON.parse(pointAttribute);
    }
    const fieldList = lineAttribute;
    fieldList.forEach((item) => {
      someDynamicFields[item.attr] = item.value;
    });
    dynamicFields.value = fieldList;
    const obj = {
      ...editor,
      ...someDynamicFields,
    };
    Object.keys(obj).forEach((key) => {
      form[key] = obj[key]
    });
    try {
      const { coordinates } = JSON.parse(form.jsonGeom)
      form.jsonLine = JSON.stringify(coordinates)
      delete form.jsonGeom
    } catch (e) {}
    form["workStartDate"] = changeDateFormat(workStartDate);
    length.value = len / 1000;
    centerDialogVisible.value = true;
  }
});
onMounted(() => {
  if (!props.editor) {
    getDeviceCategoryList();
  }
});
</script>

<template>
  <el-dialog
    v-model="centerDialogVisible"
    :title="editor ? '修改管段信息' : '添加管段信息'"
    width="1000"
    align-center
    @close="onClose"
    :close-on-press-escape="false"
    :close-on-click-modal="false"
  >
    <el-form
      ref="ruleFormRef"
      :model="form"
      class="content"
      label-position="right"
      label-width="auto"
    >
      <el-form-item label="管段长度(千米)">
        <el-input v-model="length" disabled type="number" />
      </el-form-item>
      <el-form-item label="平均埋深(米)">
        <el-input v-model="form.depth" disabled type="number" />
        <span style="position: absolute; right: -20px">米</span>
      </el-form-item>
      <el-form-item label="投运时间" prop="workStartDate">
        <el-date-picker
          v-model="form.workStartDate"
          type="date"
          placeholder="请选择投运时间"
          :size="middle"
          style="width: 100%"
        />
      </el-form-item>
      <el-form-item label="管段名称" prop="lineName" :rules="rules.lineName">
        <el-input
          v-model="form.lineName"
          maxlength="50"
          @input="(e) => checkLength(e, 'pointName', 50)"
        />
      </el-form-item>
      <el-form-item label="管段类型" prop="className" :rules="rules.className">
        <el-select
          v-model="form.className"
          placeholder="请选择管段类型"
          @change="onChange"
          :disabled="!!editor"
        >
          <el-option
            v-for="item in typeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item
        v-for="option in dynamicFields"
        :key="option.attr"
        :label="option.attr"
        :prop="option.attr"
        :rules="{
          required: option.require,
          message: `请输入${option.attr}`,
        }"
      >
        <el-input
          v-if="option.type === 1"
          v-model="form[option.attr]"
          type="number"
          pattern="[0-9]*"
        />
        <el-input v-if="option.type === 2" v-model="form[option.attr]" />
        <el-select
          v-if="option.type === 3"
          v-model="form[option.attr]"
          @change="(value) => (form[option.attr] = value)"
        >
          <el-option
            v-for="item in option.options"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
        <template v-if="option.type === 4">
          <el-upload
            ref="upload"
            action="#"
            list-type="picture-card"
            :auto-upload="false"
            :limit="9"
            accept=".jpg,.jpeg,.png,.bmp,.JPG,.JPEG,.BMP"
            v-model:file-list="form[option.attr]"
            :on-change="(file) => changeUpload(file, option.attr)"
            :before-upload="beforeUpload"
            class="no-wrap"
            :on-preview="handlePictureCardPreview"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>
          <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" />
          </el-dialog>
        </template>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" />
      </el-form-item>
      <el-form-item class="twoButtons">
        <el-button
          type="primary"
          @click="onSubmitDebounce(ruleFormRef)"
          :disabled="isRepeatSubmit"
          >保存</el-button
        >
        <el-button
          :disabled="isRepeatSubmit"
          @click="
            centerDialogVisible = false;
            emitEvents('close');
          "
          >取消</el-button
        >
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<style scoped lang="scss">
.content {
  padding: 10px 50px 0 30px;
}

.row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;

  span:nth-child(1) {
    width: 100px;
    padding-right: 12px;
    text-align: right;
  }
}

.the-img {
  position: relative;
  left: 0;
  transform: scale(0.5);
}

.twoButtons {
  :deep(.el-form-item__content) {
    display: flex;
    justify-content: space-around;
    margin-bottom: 30px;
    margin-left: 50px;
  }
}
</style>
